﻿using Microsoft.Multipoint.Sdk;
using System;
using System.Linq.Expressions;
using System.Windows;
using System.Windows.Controls;
using UTable.Core.Tools;
using System.Reflection;

namespace UTable.Core.Objects
{
    public class UObject : ContentControl, IMultipointMouseEvents
    {
        #region Dependency Properties

        public static readonly DependencyProperty PositionProperty;

        #endregion

        #region Static Methods

        #region Static Constructor

        static UObject()
        {
            FrameworkPropertyMetadata PositionMetadata = new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                new PropertyChangedCallback(OnPositionChanged));
            PositionProperty = DependencyProperty.Register("Position", typeof(Point), typeof(UObject), PositionMetadata);
        }

        #endregion

        #region Callbacks

        #region Properties Changed Callbacks

        protected static void OnPositionChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
        {
            UObject obj = dobj as UObject;
            PropertyChangedCallback handler = obj.PositionChanged;
            if (handler != null)
                handler(obj, e);
        }

        #endregion

        #endregion

        #endregion

        #region Private Members

        /// <summary>
        /// The highest type of the UObject
        /// </summary>
        private Type type;

        #endregion

        #region Constructors

        public UObject() { }

        public UObject(Type type)
        {
            InitializeType(type, typeof(UObject));
        }

        #endregion

        #region Protected Methods

        protected void InitializeType(Type originType, Type targetType)
        {
            if (!originType.IsSubclassOf(targetType))
                throw new ArgumentException("The type must derive from " + targetType.ToString());
            this.type = originType;
        }

        #endregion

        #region IObject

        #region Properties

        /// <summary>
        /// Gets or sets the position of this object relative to its parent container
        /// position is measured by the point (0, 0) of this object
        /// </summary>
        public Point Position
        {
            get { return (Point)GetValue(PositionProperty); }
            set { SetValue(PositionProperty, value); }
        }

        #endregion

        #region Events

        public event PropertyChangedCallback PositionChanged;

        #endregion

        #endregion

        #region IMultipointMouseEvents Handlers

        public event RoutedEventHandler MultipointMouseDownEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseDownHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseDownHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointMouseUpEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseUpHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseUpHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointMouseEnterEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseEnterHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseEnterHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointMouseLeaveEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseLeaveHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseLeaveHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointMouseMoveEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseMoveHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseMoveHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointMouseWheelEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointMouseWheelHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointMouseWheelHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointPreviewMouseDownEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointPreviewMouseDownHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointPreviewMouseDownHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointPreviewMouseMoveEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointPreviewMouseMoveHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointPreviewMouseMoveHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointPreviewMouseUpEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointPreviewMouseUpHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointPreviewMouseUpHandler(this, value);
            }
        }

        public event RoutedEventHandler MultipointPreviewMouseWheelEvent
        {
            add
            {
                MultipointMouseEvents.AddMultipointPreviewMouseWheelHandler(this, value);
            }

            remove
            {
                MultipointMouseEvents.RemoveMultipointPreviewMouseWheelHandler(this, value);
            }
        }

        #endregion
    }
}